Repository navigation
Resolve same-named schemas from different files as distinct components (fixes #2333) - #2349
Conversation
|
Gentle ping — open since mid-June. Recap of #2333: with Is there anything you'd like adjusted before this can be considered — naming strategy for the second component in particular? Still merges cleanly and both checks are green. |
When resolving with resolveFully/resolve, an external $ref whose target shares a name with another, not-yet-resolved external $ref placeholder caused the placeholder to be silently overwritten. ExternalRefProcessor's finalNameRec treated any existing schema that still carried a $ref as a free slot, so two distinct files defining e.g. 'Pet' collapsed into one. Only reuse the existing name when the placeholder $ref targets the same reference being resolved; otherwise fall through to a suffixed name. Fixes swagger-api#2333
0edeeb6 to
b67060a
Compare
|
Hi @seonwooj0810! Thank you for the PR :) Since this PR was opened, #2105 introduced canonical $ref identity in The regression tests cover both behaviors to stay compatible with #2105. |
|
One note here: This PR fixes the collision for |
Fixes #2333
Problem
When parsing a spec with
resolve: truewhere two schemas in different files share the same name, both references collapse into the first model. In the issue's reproducer,SomeItem(→inventory.yaml#/components/schemas/Pet, hasname) andPet(→pets.yaml#/components/schemas/Pet, hasid) both end up pointing at inventory'sPet.Root cause
ExternalRefProcessor.finalNameRecdecides which name a freshly resolved external schema gets. When the candidate name is already taken by an entry that still carries a$ref(an unresolved external placeholder, e.g. the siblingPetcomponent pointing atpets.yaml), the code unconditionally treated that slot as free and reused the name — thenaddSchemas(newRef, schema)overwrote the placeholder. The distinct second schema was lost.Fix
A
$refplaceholder slot is only safe to reuse when it targets the same reference currently being resolved. The incoming$refis now threaded intofinalNameRec; if the existing placeholder points to a different target, resolution falls through to the next suffixed name (Pet_1) instead of clobbering it. This is the conservative direction — a mismatch only ever produces an extra suffixed name, never data loss.Result on the reproducer
SomeItemcorrectly carriesnameandPetcorrectly carriesid.Test evidence
Issue2333Testwith the issue's three-file reproducer asserting the twoPetschemas resolve distinctly. Passes.swagger-parser-v3module suite: 609 tests, 0 failures, 0 errors (run with-Dmaven.javadoc.skip=true; the offline javadoc fetch and the unrelatedswagger-parser-safe-url-resolverPermittedUrlsCheckerTestfailures are pre-existing JDK 25 environment issues, not related to this change).Verification done
gh pr listsearch for the issue/keywords — none open); 2. no self-claim in the thread; 3. code-focused (.java); 4. reproduced the bug onmaster, confirmed the fix flips the behavior; 5. confirmed root symbolfinalNameRec/processRefToExternalSchemastill present onmaster; 6. n/a (no parent epic).